import Cesium from '../../Ces/Cesium';
import SuperGif from 'libgif';

function GifPrimitive(options) {
  this._canvas = undefined;

  const that = this;
  const url = options.url;
  const div = document.createElement('div');
  const img = document.createElement('img');

  img.setAttribute('rel:animated_src', url);
  img.setAttribute('rel:auto_play', '1');
  div.appendChild(img);
  const rub = new SuperGif({ gif: img });

  rub.load_url(url, () => {
    that._canvas = rub.get_canvas();
  });
  this._div = div;
  this._gif = rub;
  this._currentFrame = 0;
  this._options = options;
  const fs = 'czm_material czm_getMaterial(czm_materialInput materialInput) { \n'
    + '    czm_material material = czm_getDefaultMaterial(materialInput); \n'
    + '    vec2 st = materialInput.st; \n'
    + '    vec4 color = texture(image, st); \n'
    + '    color = czm_gammaCorrect(color); \n'
    + '    material.diffuse = color.rgb; \n'
    + '    material.alpha = color.a; \n'
    + '    material.shininess = 8.0; \n' // Sharpen highlight
    + '    return material; \n'
    + '} \n';

  this._fs = options.fragmentShaderSource?? fs
  this._primitive = undefined;
  this._appearance = options.appearance;
  this._dirty = false;
  this._show = true;
}

Object.defineProperties(GifPrimitive.prototype, {
  canvas: {
    get() {
      return this._canvas;
    },
  },
  appearance: {
    get() {
      return this._appearance;
    },
  },
  show: {
    get() {
      return this._show;
    },
    set(value) {
      this._show = value;
    },
  },
});

GifPrimitive.prototype.updateGeometry = function (options) {
  this._options = options;
  this._dirty = true;
};

GifPrimitive.prototype.update = function (frameState) {
  if (!Cesium.defined(this._canvas) || !this._show) {
    return;
  }

  if (this._dirty || !Cesium.defined(this._primitive)) {
    this._dirty = false;
    this._primitive = new Cesium.Primitive(this._options);
    this._primitive.appearance = this._appearance;
  }

  if (!Cesium.defined(this._texture)) {
    this._createTexture(frameState.context);
  }

  if (frameState.passes.render) {
    this._primitive.update(frameState);
  }

  if (this._currentFrame !== this._gif.get_current_frame()) {
    this._currentFrame = this._gif.get_current_frame();
    this._texture.copyFrom({
      source: this._canvas
    });
  }
};

GifPrimitive.prototype._createTexture = function (context) {
  const sampler = new Cesium.Sampler({
    wrapS: Cesium.TextureWrap.CLAMP_TO_EDGE,
    wrapT: Cesium.TextureWrap.CLAMP_TO_EDGE,
    minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
    magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
  });

  this._texture = new Cesium.Texture({
    context,
    source: this._canvas,
    sampler,
  });

  const _uniforms = {
    image: this._texture,
  };

  if (Cesium.defined(this._options.uniforms)) {
    Object.assign(_uniforms, this._options.uniforms);
  }

  this._appearance.material = new Cesium.Material({
    fabric: {
      uniforms: _uniforms,
      source: this._fs,
    },
  });
};

GifPrimitive.prototype.isDestroyed = function () {
  return false;
};

GifPrimitive.prototype.destroy = function () {
  this._primitive = this._primitive && this._primitive.destroy();
  this._texture = this._texture && this._texture.destroy();
  this._div.remove();
  if (Cesium.defined(this._canvas)) {
    this._canvas.remove();
  }
  this._canvas = this._div = undefined;

  return Cesium.destroyObject(this);
};


export default GifPrimitive;
